function [X, Y] = genLowHighImgPatchPairs(TrainImgPath, Param, bRandPerm)

TempPath = fullfile(fileparts(TrainImgPath), ['%Temp-' num2str(round(rand*1e4))]);
% TempPath = fullfile(fileparts(TrainImgPath), '%Temp');
srdata.mkdirs(TempPath);

%%
% group_size = 5e3;
group_size = 5e4;

% padding = abs(x_size - y_size) / 2;
% y_stride = Param.stride + padding;

X = zeros([Param.x_size, Param.x_size, group_size]);
Y = zeros([Param.y_size, Param.y_size, group_size]);

Images = srimg.dirimgs(TrainImgPath, true);

%%
fprintf('\nStart generating low resolution (LR) and high resolution (HR) image pairs ...\n')
pp = 0;  count = 0;
ImgNum = length(Images);
for scale = Param.scales
    for i = 1 : ImgNum
        fprintf('\tScale %d, Image %d/%d\n', scale, i, ImgNum);
        
        y = srimg.imread(fullfile(TrainImgPath, Images{i}), scale);
        
        [y_bic, x] = srimg.im2lr(y, scale, 'bicubic');
        if Param.x_size == Param.y_size
            x = srimg.im2colstep(y_bic, [Param.x_size, Param.x_size], [Param.stride Param.stride]);
            y = srimg.im2colstep(y, [Param.y_size, Param.y_size], [Param.stride Param.stride]);
            x = reshape(x, [Param.x_size Param.x_size size(x, 2)]);
            y = reshape(y, [Param.y_size Param.y_size size(y, 2)]);
        else
            [x, y] = gen_patch_pair(x, y, scale, Param.stride, Param.x_size, Param.y_size);
        end
        
        len = pp(end);
        pp  = pp(end)+1 : pp(end)+size(x, 3);
        if pp(end) > group_size
            pp = 1 : size(x, 3);
            count = count + 1;
            xx = X(:, :, 1 : len);
            yy = Y(:, :, 1 : len);
            save(fullfile(TempPath, ['tempdata' num2str(count) '.mat']), 'i', 'xx', 'yy');
        end
        
        X(:, :, pp) = x;
        Y(:, :, pp) = y;
    end
end

len = pp(end);
X = X(:, :, 1 : len);
Y = Y(:, :, 1 : len);
disp('All LR and HR image patch pairs are generated!');

%%
if count > 0
    [X, Y] = srimg.MergeMats(TempPath, 'tempdata*.mat', X, Y);
end
rmdir(TempPath, 's')

%%
if bRandPerm
    order = randperm(size(X, 3));
    X = X(:, :, order);
    Y = Y(:, :, order);
end

function [xx, yy] = gen_patch_pair(x, y, scale, stride, x_size, y_size)
xx = zeros([x_size x_size prod(floor(size(x)/x_size))]);
yy = zeros([y_size y_size prod(floor(size(y)/y_size))]);

count = 0;
[hei, wid] = size(x);
x_p = floor((x_size - 1)/2);
y_p = floor((y_size + scale)/2 - 1);
for r_x = 1 : stride : hei - x_size + 1
    for c_x = 1 : stride : wid - x_size + 1
        r_y = scale * (r_x + x_p) - y_p;
        c_y = scale * (c_x + x_p) - y_p;
        
        count = count + 1;
        xx(:, :, count) = x(r_x : r_x + x_size - 1, c_x : c_x + x_size - 1);
        yy(:, :, count) = y(r_y : r_y + y_size - 1, c_y : c_y + y_size - 1);
    end
end

xx = xx(:, :, 1 : count);
yy = yy(:, :, 1 : count);
